package cat.joronya.supermanager.service.htmlcleanerImpl;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.htmlcleaner.ContentNode;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;

import android.util.Log;

import cat.joronya.supermanager.Supermanager;
import cat.joronya.supermanager.privateleague.PrivateLeague;
import cat.joronya.supermanager.service.PrivateLeaguesParser;
import cat.joronya.supermanager.team.Team;

public class PrivateLeaguesParserImpl implements PrivateLeaguesParser
{
	protected ArrayList<PrivateLeague> privateLeagues;
	
	// XPATHs per treure dades de les pagines
	// private leagues XPATH
	private static final String PRIVATE_LEAGUES_XPATH = "//td[@background='gif/ligaprivada.gif']";
	// private league teams XPATH
	private static final String PRIVATE_LEAGUE_TEAMS_XPATH = "//td[@background='gif/clasificacionpos.gif']";
	// jornada
	private static final String PRIVATE_LEAGUE_DAY_XPATH = "//font[@class='blanca16']";
	
	public ArrayList<PrivateLeague> getPrivateLeagues() 
	{
		return privateLeagues;
	}

	public long parse(String html)
			throws Exception 
	{
		long start = System.nanoTime();
		
		try
		{
			privateLeagues = new ArrayList<PrivateLeague>();

			HtmlCleaner cleaner = new HtmlCleaner();
			TagNode node = cleaner.clean(html);
			
			// cerquem les lligues
			Object[] tdPL = node.evaluateXPath(PRIVATE_LEAGUES_XPATH);
			TagNode tagPLHeader = (TagNode) tdPL[0];
			TagNode tagPLTable = tagPLHeader.getParent().getParent();
			
			// trs de lligues privades per veure si n'hi ha
			List trs = tagPLTable.getChildren();
			
			if( trs.size() >= 3 )
			{
				// llistem els equips, diferents trs
				for (Object objTr : tagPLTable.getChildren()) 
				{
					// descartem el tr del titular
					if (tagPLHeader.getParent().equals(objTr))
						continue;

					// els tds
					List tds = ((TagNode) objTr).getChildren();

					// primer td
					TagNode td0 = (TagNode) tds.toArray()[0];

					// si es l'ultim acabem, es a dir te
					// background='gif/ligasabajo.gif'
					if ("gif/ligasabajo.gif".equals(td0
							.getAttributeByName("background")))
						continue;

					// si no hi han lligues i trobem missatge, continue
					List td0Childs = td0.getChildren();
					if( td0Childs.toArray()[0] instanceof ContentNode )
					{
						ContentNode contentNode = (ContentNode)td0Childs.toArray()[0];
						String contentString = contentNode.toString();
						if( "En estos momentos no tienes ningún equipo participando en Ligas Privadas.".equals(contentString) )
							continue;
					}
					
					// inicialitzem private league
					PrivateLeague pl = new PrivateLeague();
					for (Object td0Child : td0.getChildren()) {
						TagNode a = (TagNode) td0Child;
						if ("a".equals(a.getName())) {
							String href = a.getAttributeByName("href");
							String id = href.replaceFirst("verprivada.php.id_pri=",
							"");
							pl.setId(id);
							for (Object aContent : a.getChildren()) {
								if (aContent instanceof ContentNode)
									pl.setName(aContent.toString());
							}
						}
					}

					// segon td
					TagNode td1 = (TagNode) tds.toArray()[1];
					for (Object td1Child : td1.getChildren()) {
						if (td1Child instanceof ContentNode)
							pl.setNumberOfTeams(td1Child.toString());
					}

					// guardem al llistat de private leagues
					privateLeagues.add(pl);
				}
			}
			
		}
		catch(Exception e)
		{}
		
		return System.nanoTime()-start;
	}
	
	public long parseTeams(String html, PrivateLeague privateLeague) throws Exception
	{
		long start = System.nanoTime();
		
		try
		{
			HashMap<String, Team> teams = new HashMap<String, Team>();
			NumberFormat nf = NumberFormat.getInstance(new Locale("es", "ES"));
			
			HtmlCleaner cleaner = new HtmlCleaner();
			TagNode node = cleaner.clean(html);
			
			// cerquem la jornada de la lliga privada
			Object[] font = node.evaluateXPath(PRIVATE_LEAGUE_DAY_XPATH);
			int day = -1;
			if( font.length == 0 )
			{
				Log.d(Supermanager.TAG,"Error parsing verprivada.php... no day found");
				throw new Exception();
			}
			TagNode fontTag = (TagNode) font[0];
			// children de font, el b
			for (Object bTag: fontTag.getChildren())
			{
				TagNode bTagNode = (TagNode)bTag;
				if (!"b".equals((bTagNode).getName()) )
					continue;
				
				for (Object bContent: bTagNode.getChildren())
				{
					if( bContent instanceof ContentNode )
					{
						String tmpDay = ((ContentNode)bContent).toString();
						Integer dayObject = Integer.valueOf(0);
						Pattern p = Pattern.compile("(\\S*)\\s-\\sJornada\\s(\\S*)");
	       				Matcher m = p.matcher(tmpDay);
	       				if( m.find() ) 
	       				{
	       					try{
	       						String dayParsed = m.group(2);
	       						String lliga = m.group(1);
	       						Log.d(Supermanager.TAG,"getPrivateLeagueTeams tmpDay: "+tmpDay+", lliga: "+lliga+", dayParsed: "+dayParsed);
	       						dayObject = Integer.valueOf(nf.parse(dayParsed).intValue());
	           				}catch(ParseException pe){
	           					dayObject = Integer.valueOf("0");
	           				}
	       				}
	       				day = dayObject.intValue();
	       				Log.d(Supermanager.TAG,"PrivateLeagueSync getPrivateLeagueTeams parsing day: "+day);
					}
				}
				
			}

			// cerquem els equips de la lliga
			Object[] tdLT = node.evaluateXPath(PRIVATE_LEAGUE_TEAMS_XPATH);
			if (tdLT.length == 0) {
				Log.d(Supermanager.TAG,"Error parsing verprivada.php... no list of team found");
				throw new Exception();
			}
			TagNode tagLTHeader = (TagNode) tdLT[0];
			TagNode tagLTTable = tagLTHeader.getParent().getParent();

			// llistem els equips, diferents trs
			for (Object objTr : tagLTTable.getChildren()) {
				// descartem el tr del titular
				if (tagLTHeader.getParent().equals(objTr))
					continue;

				// els tds
				List tds = ((TagNode) objTr).getChildren();

				// el nom de l'equip sera la key del HashMap
				String name = null;

				// segon td
				TagNode td1 = (TagNode) tds.toArray()[1];
				for (Object td1Child : td1.getChildren()) {
					if (td1Child instanceof ContentNode) {
						name = td1Child.toString();
						continue;
					}
				}

				// si no trobem el nom de l'equip, continuem i descartem la linia
				if (name == null) {
					Log.d(Supermanager.TAG,	"Error parsing private league teams, team name not found.");
					continue;
				}

				// creem equip per omplir-lo
				Team t = new Team();
				t.setName(name.trim());
				t.setDay(day);

				// tercer td
				TagNode td2 = (TagNode) tds.toArray()[2];
				for (Object td2Child : td2.getChildren()) {
					if (td2Child instanceof ContentNode) {
						String manager = "unknown";
						String city = "unknown";
						Pattern p = Pattern.compile("([^\\(]*)\\(([^\\)]*)\\)");
						Matcher m = p.matcher(td2Child.toString());
						if (m.find()) {
							manager = m.group(1);
							city = m.group(2);
						}
						t.setManager(manager.trim());
						t.setCity(city.trim());
						continue;
					}
				}

				// quart td
				TagNode td3 = (TagNode) tds.toArray()[3];
				for (Object td3Child : td3.getChildren()) {
					if (td3Child instanceof ContentNode) {
						Float points;
						try {
							points = Float.valueOf(nf.parse(td3Child.toString())
									.floatValue());
						} catch (ParseException pe) {
							points = Float.valueOf("0");
						}
						t.setPoints(points);
						continue;
					}
				}

				// guardem l'equip parsejat al HashMap
				teams.put(name.trim(), t);
			}

			// guardem els equips a la lliga privada
			privateLeague.setTeams(teams);
		}
		catch(Exception e)
		{}
		
		return System.nanoTime()-start;
	}

	public long parseGeneralTeams(String html, PrivateLeague privateLeague) throws Exception 
	{
		long start = System.nanoTime();
		
		try
		{
			HashMap<String, Team> teams = privateLeague.getTeams();
			NumberFormat nf = NumberFormat.getInstance(new Locale("es", "ES"));
			
			HtmlCleaner cleaner = new HtmlCleaner();
			TagNode node = cleaner.clean(html);

			// cerquem els equips de la lliga
			Object[] tdLT = node.evaluateXPath(PRIVATE_LEAGUE_TEAMS_XPATH);
			if (tdLT.length == 0) {
				Log.d(Supermanager.TAG, "Error parsing verprivada.php... no list of team found");
				throw new Exception();
			}
			TagNode tagLTHeader = (TagNode) tdLT[0];
			TagNode tagLTTable = tagLTHeader.getParent().getParent();

			// llistem els equips, diferents trs
			for (Object objTr : tagLTTable.getChildren()) {
				// descartem el tr del titular
				if (tagLTHeader.getParent().equals(objTr))
					continue;

				// els tds
				List tds = ((TagNode) objTr).getChildren();

				// nom de l'equip per identificar-lo i continuar omplint dades
				String name = null;

				// segon td
				TagNode td1 = (TagNode) tds.toArray()[1];
				for (Object td1Child : td1.getChildren()) {
					if (td1Child instanceof ContentNode) {
						name = td1Child.toString();
						continue;
					}
				}

				// error, no trobem l'equip al llistat parsejat a
				// getPrivateLeagueTeams
				if (name == null) {
					Log.d(Supermanager.TAG, "Error parsing private league teams general, team name not found.");
					continue;
				}
				// creem equip per omplir-lo
				Team t = teams.get(name.trim());
				
				// tercer td
				TagNode td2 = (TagNode) tds.toArray()[2];
				for (Object td2Child : td2.getChildren()) {
					if (td2Child instanceof ContentNode) {
						String manager = "unknown";
						String city = "unknown";
						Pattern p = Pattern.compile("([^\\(]*)\\(([^\\)]*)\\)");
						Matcher m = p.matcher(td2Child.toString());
						if (m.find()) {
							manager = m.group(1);
							city = m.group(2);
						}
						t.setManager(manager.trim());
						t.setCity(city.trim());
						continue;
					}
				}

				// quart td
				TagNode td3 = (TagNode) tds.toArray()[3];
				for (Object td3Child : td3.getChildren()) {
					if (td3Child instanceof ContentNode) {
						Float general;
						try {
							general = Float.valueOf(nf.parse(td3Child.toString())
									.floatValue());
						} catch (ParseException pe) {
							general = Float.valueOf("0");
						}
						t.setGeneral(general);
						continue;
					}
				}
			}

			// guardem els equips a la lliga privada
			privateLeague.setTeams(teams);
		}
		catch(Exception e)
		{}
		
		return System.nanoTime()-start;
	}

	public long parseBrokerTeams(String html, PrivateLeague privateLeague)throws Exception 
	{
		long start = System.nanoTime();
		
		try
		{
			HashMap<String, Team> teams = privateLeague.getTeams();
			NumberFormat nf = NumberFormat.getInstance(new Locale("es", "ES"));
			
			HtmlCleaner cleaner = new HtmlCleaner();
			TagNode node = cleaner.clean(html);
			
			// cerquem els equips de la lliga
			Object[] tdLT = node.evaluateXPath(PRIVATE_LEAGUE_TEAMS_XPATH);
			if (tdLT.length == 0) {
				Log.d(Supermanager.TAG, "Error parsing verprivada.php... no list of team found");
				throw new Exception();
			}
			TagNode tagLTHeader = (TagNode) tdLT[0];
			TagNode tagLTTable = tagLTHeader.getParent().getParent();

			// llistem els equips, diferents trs
			for (Object objTr : tagLTTable.getChildren()) {
				// descartem el tr del titular
				if (tagLTHeader.getParent().equals(objTr))
					continue;

				// els tds
				List tds = ((TagNode) objTr).getChildren();

				// nom de l'equip com a key per trobar-lo al array de teams
				String name = null;

				// segon td
				TagNode td1 = (TagNode) tds.toArray()[1];
				for (Object td1Child : td1.getChildren()) {
					if (td1Child instanceof ContentNode) {
						name = td1Child.toString();
						continue;
					}
				}

				// error, no trobem l'equip al llistat parsejat a
				// getPrivateLeagueTeams
				if (name == null) {
					Log.d(Supermanager.TAG, "Error parsing private league teams broker, team name not found.");
					continue;
				}
				// creem equip per omplir-lo
				Team t = teams.get(name.trim());

				// tercer td
				TagNode td2 = (TagNode) tds.toArray()[2];
				for (Object td2Child : td2.getChildren()) {
					if (td2Child instanceof ContentNode) {
						String manager = "unknown";
						String city = "unknown";
						Pattern p = Pattern.compile("([^\\(]*)\\(([^\\)]*)\\)");
						Matcher m = p.matcher(td2Child.toString());
						if (m.find()) {
							manager = m.group(1);
							city = m.group(2);
						}
						t.setManager(manager.trim());
						t.setCity(city.trim());
						continue;
					}
				}

				// quart td
				TagNode td3 = (TagNode) tds.toArray()[3];
				for (Object td3Child : td3.getChildren()) {
					if (td3Child instanceof ContentNode) {
						Integer broker;
						try {
							broker = Integer.valueOf(nf.parse(td3Child.toString())
									.intValue());
						} catch (ParseException pe) {
							broker = Integer.valueOf("0");
						}
						t.setBroker(broker);
						continue;
					}
				}
			}

			// guardem els equips a la lliga privada
			privateLeague.setTeams(teams);
		}
		catch(Exception e)
		{}
		
		return System.nanoTime()-start;
	}
}
